package com.inspectortime.webapp.inspector.scheduleRule;

import java.util.Calendar;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;

import com.inspectortime.calendar.Timeslot;
import com.inspectortime.domain.Inspector;
import com.inspectortime.domain.ScheduleRule;
import com.inspectortime.domain.type.FrequencyType;
import com.inspectortime.util.CalendarUtil;

/**
 * Performs the functionality necessary to override a particular day within a recurring
 * scheduleRule with a non-recurring one.  Allows a user to change one timeslot without
 * editing the entire non-recurring one
 * 
 * @author bones
 *
 */
public class OverrideRecurringScheduleRuleController extends ScheduleRuleController {
	
	private static Log log = LogFactory.getLog(EditScheduleRuleController.class);

	public OverrideRecurringScheduleRuleController() {
		super();
	}
	
	
	protected Object formBackingObject(HttpServletRequest request) throws Exception {
		
		ScheduleRule originalRule = null;
		ScheduleRule newRule = null;
		
		String originatingRuleId = request.getParameter("ruleId");
		String day = request.getParameter("day");
		String month = request.getParameter("month");
		String year = request.getParameter("year");
		
		String inspectorId = request.getParameter("inspectorId"); 
		Inspector inspector = repository.loadInspector(inspectorId);
		originalRule = inspector.getScheduleRuleById(originatingRuleId);
			
		if (originalRule.getFrequencyType() != FrequencyType.DAY_OF_WEEK) {
			throw new RuntimeException("Trying to override a non-recurring scheduleRule.  RuleId: " + originatingRuleId);
		} 
			
		newRule =  copyToNonRecurringRule(originalRule, day, month, year);
		
		return newRule;
	}
	
	protected ModelAndView onSubmit(HttpServletRequest request,	HttpServletResponse response, Object command, BindException errors)
		throws Exception {

		log.debug("OverrideRecurringScheduleRuleController.onSubmit");
		ScheduleRule scheduleRule = (ScheduleRule) command;
		
		//if this scheduleRule was moved out of the range of the original recurring one, 
		//then override the original one with an unavailable timeslot
		String originalId = request.getParameter("originalRuleId");
		String inspectorId = request.getParameter("inspectorId");
		Inspector inspector = repository.loadInspector(inspectorId);
		ScheduleRule originalRule = inspector.getScheduleRuleById(originalId);
		
		ScheduleRule overrider = null;
		Timeslot currentTimeslot = new Timeslot(scheduleRule);
		Timeslot originalTimeslot = new Timeslot(originalRule);
		if (!currentTimeslot.overlapsWith(originalTimeslot)) {
				
			//User has tried to override with a timeslot that doesn't have "overirding" times.  So we'll automatically 
			//override the non-recurring rules's times with an "unavailable" one
			overrider = copyToNonRecurringRule(originalRule, request.getParameter("day"), request.getParameter("month"), request.getParameter("year"));
			overrider.setAvailable(false);
		}
		
		inspector.getScheduleRules().add(scheduleRule);
		if (overrider != null) {
			inspector.getScheduleRules().add(overrider);
		}
		inspector.save();
	
		ModelAndView mv = new ModelAndView(getSuccessView());
		mv.addObject("start", buildUrlStartDate(scheduleRule.getStartDate()));
		mv.addObject("msg", "addEditScheduleRule.rule.overriden");
		mv.addObject("inspectorId", request.getParameter("inspectorId"));
		return mv;
	
	}
	
	/**
	 * Creates a non-recurring ScheduleRule and copies the necessary values from a recurring ScheduleRule into it
	 * 
	 * @param originalRule
	 * @param startDay
	 * @param startMonth
	 * @param startYear
	 * @return
	 */
	private ScheduleRule copyToNonRecurringRule(ScheduleRule originalRule, String startDay, String startMonth, String startYear) {
		
		//Make sure we don't end up with invalid data.  Not expected to happen
		if (!StringUtils.hasText(startDay) || !StringUtils.hasText(startMonth) || !StringUtils.hasText(startYear)) {
			throw new RuntimeException("Missing Required Parameters to copy scheduleRule. originalRule: " + originalRule.getId() + ", day: " + startDay + ", month:" + startMonth + ", year:" + startYear);
		}
		
		ScheduleRule newRule =  factory.createScheduleRule();
		newRule.setStartHour(originalRule.getStartHour());
		newRule.setStartMinute(originalRule.getStartMinute());
		newRule.setEndHour(originalRule.getEndHour());
		newRule.setEndMinute(originalRule.getEndMinute());
		newRule.setAvailable(originalRule.isAvailable());
		newRule.setFrequencyType(FrequencyType.SINGLE_DAY);
			
		Calendar startDate = CalendarUtil.createDayCalendar(Integer.parseInt(startYear), Integer.parseInt(startMonth), Integer.parseInt(startDay));
		newRule.setStartDate(startDate);
		newRule.setEndDate(startDate);
		
		return newRule;
	}

}
